#include <pantheios/pantheios.hpp>
#include <pantheios/inserters.hpp>
#include <boost/lexical_cast.hpp>
#include "main_game_shell.h"
#include "pageinfogetter.hpp"
#include <ltobjectcreate.h>
#include "server_object_create.h"
#include "valuerange.hpp"
#include "automessage.h"
#include "msgids.h"
#include <boost/lexical_cast.hpp>
#include <boost/bind.hpp>
#include "iltserver.h"
#include "light_system.h"
#include "ltbasedefs.h"

game_logic_shell::~game_logic_shell() {
}

game_logic_shell::game_logic_shell() : m_light_system(new light_system(this)) {
}

std::vector<binding_shader_info_type> game_logic_shell::ms_shader_infos ;

void game_logic_shell::send_create_binding_shader_message(HCLIENT hclient,
                                                          LPBASECLASS object,
                                                          const char* name) {
    HOBJECT obj = object->GetHOBJECT() ;  
    ms_shader_infos.push_back(binding_shader_info_type(hclient, obj, name)) ;
}

static void send_a_binding_shader_message(const binding_shader_info_type& info) {
    using namespace Utility ;
    int effect_number = page_info_getter::Instance().get<int>
        ("car_infos", info.Name, "effect_number", 0) ;
    
    CAutoMessage msg ;
    
    msg.Writeuint8(MSG_BINDING_SHADER) ;
    pantheios::log_DEBUG("object pointer is ", pantheios::hex_ptr(info.Object)) ;
    msg.WriteObject(info.Object) ;
    msg.Writeint32(effect_number) ;
    for(int i = 0 ;i < effect_number ; ++i) {
        std::string effect_name = std::string("effect") + boost::lexical_cast<std::string>(i) ;
        int effect = page_info_getter::Instance().get<int>("car_infos", info.Name, effect_name, -1) ;
        msg.Writeint32(effect) ;
    }
    g_pLTServer->SendToClient(msg.Read(), info.Hclient, NULL) ;
    
}

void game_logic_shell::send_all_binding_infos() {
    if(!ms_shader_infos.empty()) {
        // now just sleep for a while
        Sleep(100) ;
        std::for_each(ms_shader_infos.begin(),
                      ms_shader_infos.end(),
                      boost::bind(send_a_binding_shader_message, _1)) ;
         ms_shader_infos.clear() ;
    }
    
}

LPBASECLASS game_logic_shell::create_jupiter_car(const char* instance_name) {
    using namespace Utility ;
    ObjectCreateStruct objCreateStruct;
    LTVector vPos, vStartPos;
    LTRotation rStartRot;
    bind_object_object_info_from_page("car_infos", instance_name, &objCreateStruct) ;
    LPBASECLASS obj = 0 ;

    obj = create_object("player_server", &objCreateStruct) ;
    
    return obj ;
}

// just for test
//FIXME
void game_logic_shell::create_attachment(LPBASECLASS obj) 
{

    
    ObjectCreateStruct objCreateStruct;
    LTVector vPos, vStartPos;
    LTRotation rStartRot;
    objCreateStruct.Clear();
    objCreateStruct.m_ObjectType = OT_MODEL;
    objCreateStruct.m_Flags = FLAG_VISIBLE | FLAG_SHADOW |FLAG_FORCEOPTIMIZEOBJECT|FLAG_FULLPOSITIONRES  ;
    strcpy(objCreateStruct.m_SkinNames[0], "\\modeltextures\\newcar\\car_wheel_d.dtx") ;
    strcpy(objCreateStruct.m_SkinNames[1], "\\modeltextures\\newcar\\car_wheel_n.dtx") ;
    strcpy(objCreateStruct.m_SkinNames[2], "\\modeltextures\\newcar\\car_wheel_s.dtx") ;
    strcpy(objCreateStruct.m_Filenames[0], "\\models\\newcar\\011.ltb") ;
    strcpy(objCreateStruct.m_RenderStyleNames[0], "rs\\car_shader.ltb") ;
    objCreateStruct.m_Scale = LTVector(0.015, 0.015, 0.015) ;
    LPBASECLASS obj2 = create_object("player_server", &objCreateStruct) ;
    if(obj2)
        g_pLTServer->CPrint("create object in server ok........................") ;
    HATTACHMENT att ; 
    LTVector oo ;
    oo.x = oo.y = oo.z = 0.0f ;
    oo.x += 0.9f ;
    LTRotation rr(LTVector(0.0, 0.0, 1.0), 3.14 / 2.0f) ;
    g_pLTServer->CreateAttachment(obj->GetHOBJECT(), obj2->GetHOBJECT(), "left",&oo, &rr, &att) ;
    obj2 = create_object("player_server", &objCreateStruct) ;
    g_pLTServer->CreateAttachment(obj->GetHOBJECT(), obj2->GetHOBJECT(), "back_left",&oo, &rr, &att) ;
    strcpy(objCreateStruct.m_Filenames[0], "\\models\\newcar\\012.ltb") ;
    obj2 = create_object("player_server", &objCreateStruct) ;
    LTRotation rr2(LTVector(0.0, 0.0, 1.0), 3.14 / 2.0f) ;
    g_pLTServer->CreateAttachment(obj->GetHOBJECT(), obj2->GetHOBJECT(), "right",&oo, &rr2, &att) ;
    obj2 = create_object("player_server", &objCreateStruct) ;
    oo.x -= 0.3f ;
    g_pLTServer->CreateAttachment(obj->GetHOBJECT(), obj2->GetHOBJECT(), "back_right",&oo, &rr2, &att) ;
    
    
}


    
